import React,{Fragment,Component} from 'react'
const FaContext = React.createContext()
/*
  使用 context 可以创建一个上下文对象 这个可以非常方便的让我们用在 祖孙组件 中传值的使用
    使用 const {Provider,Consumer} = React.createContext() 可以返回一个组件
    可以分别解构赋值出 Provider（提供者） 和 Consumer（接收者）

    Provider（提供者） 组件 负责提供值 所以这个肯定是放在 祖先组件上的 使用 value 属性传递一个上下文共享的数据
      如:
        <Provider value={{name:'Jimmy',age:22}}>
          <B />
        </Provider>
        只要这样写了 B组件极其B的所有后代组件都可以接收 这个传递的上下文对象了

    当作为子组件是类组件的时候 只需要使用 static 关键字创建一个变量 这个变量 赋值的就是创建的那个上下文对象
      这样 在类组件中 使用 this.context 就可以获取到赋值的那个上下文了
    
    当子组件是函数组件的时候 哪里需要使用到上下文对象 就使用
      <Consumer>
        {value => {
          return JSX
          // 其中 value 就是提供者传递的上下文参数
        }}
      </Consumer>

    总结： 这个也是组件传值的一种方式  这个就和 VUE 的 provider 和 inject 思想是很像的
      不过一般比较复杂还是建议使用 redux 
*/ 
export default function Count(){

  const [count] = React.useState(0)  
  const [name] = React.useState('Jimmy')  

  return (
    <Fragment>
      <FaContext.Provider value={{count,name}} >
        <A />
      </FaContext.Provider>
    </Fragment>
  )
}

function A(){
  return (
    <div>
      <h2>我是A组件</h2>
      <B />
      <C />
    </div>
  )
}

function B(){
  return (
    <div>
      
        <h2>我是B组件</h2>
        <p>我接到祖组件的值是：
        <FaContext.Consumer>
          {value=>
          value.name
        }
        </FaContext.Consumer>
        </p>
        {/* <p>我接到祖组件的名字是：{value=>value.name}</p> */}
      
      
    </div>
  )
}

class C extends Component{

  static contextType = FaContext

  render(){
    return (
      <div>
        <h2>我是C组件</h2>
        <p>我接到祖组件的值是：{this.context.count}</p>
      </div>
    )
  }
}